package lib.control;

import lib.JBierSubAdapter;
import lib.JOpenSubAdapter;
import lib.JPodnapisiAdapter;
import lib.logging.Logger;
import lib.model.*;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SubtitleControl {

    private JBierSubAdapter jBierSubAdapter;
    private JOpenSubAdapter jOpenSubAdapter;
    private JPodnapisiAdapter jPodnapisiAdapter;
    private VideoFileParser videoFileParser;

    public SubtitleControl(VideoType videoFileType) {
        videoFileParser = new VideoFileParser();
        if (videoFileType == VideoType.EPISODE){
            jBierSubAdapter = new JBierSubAdapter();
        }else if (videoFileType == VideoType.MOVIE){
            jOpenSubAdapter = new JOpenSubAdapter();
            jPodnapisiAdapter = new JPodnapisiAdapter();
        }
    }

    public List<Subtitle> getSubtitles(MovieFile movieFile, boolean exactMatch, String... languagecode) {
    	Logger.instance.trace("SubtitleControl", "getSubtitles", "Movie");
        List<Subtitle> listFoundSubtitles = new ArrayList<Subtitle>();
        listFoundSubtitles.addAll(jOpenSubAdapter.searchSubtitles(movieFile, languagecode));
        listFoundSubtitles.addAll(jPodnapisiAdapter.searchSubtitles(movieFile, languagecode[0]));
        return this.getSubtitlesFiltered(listFoundSubtitles, movieFile, exactMatch);
    }

    public List<Subtitle> getSubtitles(EpisodeFile episodeFile, boolean exactMatch, String... languagecode) {
    	Logger.instance.trace("SubtitleControl", "getSubtitles", "Episode");
    	List<Subtitle> listFoundSubtitles = getSubtitlesRSS(episodeFile,exactMatch,languagecode);
		
		if (listFoundSubtitles.size() == 0){
				listFoundSubtitles.addAll(jBierSubAdapter.searchSubtitles(
						episodeFile, languagecode[0]));
			return this.getSubtitlesFiltered(listFoundSubtitles, episodeFile, exactMatch);
		}else{
		    Logger.instance.debug("Bierdopje RSS parse found subtitle");
		}
		
		return listFoundSubtitles;
    }
    
    public List<Subtitle> getSubtitlesRSS(EpisodeFile episodeFile, boolean exactMatch, String... languagecode) {
    	Logger.instance.trace("SubtitleControl", "getSubtitlesRSS", "Episode");
    	List<Subtitle> listFoundSubtitles = new ArrayList<Subtitle>();
    	
    	listFoundSubtitles.addAll(jBierSubAdapter.getRssSubs(episodeFile, languagecode[0]));
		//set exactMatch = true here because we want the most correct answer for the user 
		listFoundSubtitles = this.getSubtitlesFiltered(listFoundSubtitles, episodeFile, true);
		
		return listFoundSubtitles;
    }

    protected List<Subtitle> getSubtitlesFiltered(List<Subtitle> listFoundSubtitles, VideoFile videoFile, boolean exactMatch) {
    	Logger.instance.trace("SubtitleControl", "getSubtitlesFiltered", "");
        boolean found = false;
        List<Subtitle> listFilteredSubtitles;
        listFilteredSubtitles = new ArrayList<Subtitle>();

        String subRequest = " ";
        if (!(videoFile.getFilename() == null)){
        	subRequest = videoFile.getFilename().toLowerCase();
        	subRequest = subRequest.replace("." + videoFile.getExtension(), "");
        }

        Pattern p = Pattern.compile(subRequest.replaceAll(" ", "[. ]"), Pattern.CASE_INSENSITIVE);

        for (Subtitle subtitle : listFoundSubtitles) {
            Matcher m = p.matcher(subtitle.getFilename().toLowerCase().replace(".srt", ""));
            if (m.matches()) {
                subtitle.setSubtitleMatchType(SubtitleMatchType.EXACT);
                subtitle.setQuality(this.videoFileParser.getQualityKeyword(subtitle.getFilename()));
                Logger.instance.debug("getSubtitlesFiltered: found EXACT match: " + subtitle.getFilename());
                listFilteredSubtitles.add(subtitle);
                found = true;
            }
        }

        if (!found) {
            // check keywords
        	String keywordsFile = this.videoFileParser.getQualityKeyword(subRequest);
        	
            for (Subtitle subtitle : listFoundSubtitles) {
            	boolean foundKeywordMatch = checkKeywordSubtitleMatch(subtitle, keywordsFile);

                if (foundKeywordMatch) {
                    subtitle.setSubtitleMatchType(SubtitleMatchType.KEYWORD);
                    subtitle.setQuality(videoFileParser.getQualityKeyword(subtitle.getFilename()));
                    Logger.instance.debug("getSubtitlesFiltered: found KEYWORD/FILESIZE match: " + subtitle.getFilename());
                    listFilteredSubtitles.add(subtitle);
                    found = true;
                }
            }
        }

        if (!found && videoFile.getPath() != null && videoFile.getFilename() != null) {
            //check keywords based on filesize if no keywords found in file.
        	String keywordsFile = this.videoFileParser.getQualityKeyword(videoFile.getPath().getAbsolutePath());
        	if (keywordsFile.equalsIgnoreCase("")){
	        	long size = (new File(videoFile.getPath(), videoFile.getFilename())).length() / 1024 / 1024;
	            if (size < 400) {
	            	keywordsFile = "dvdrip xvid hdtv";
	            } else if (size < 1200) {
	            	keywordsFile = "720p hdtv";
	            } else if (size < 1600) {
	            	keywordsFile = "web dl";
	            }
        	}

            for (Subtitle subtitle : listFoundSubtitles) {
            	boolean foundKeywordMatch = checkKeywordSubtitleMatch(subtitle, keywordsFile);

                if (foundKeywordMatch) {
                    subtitle.setSubtitleMatchType(SubtitleMatchType.KEYWORD);
                    subtitle.setQuality(videoFileParser.getQualityKeyword(subtitle.getFilename()));
                    Logger.instance.debug("getSubtitlesFiltered: found KEYWORD/FILESIZE match: " + subtitle.getFilename());
                    listFilteredSubtitles.add(subtitle);
                    found = true;
                }
            }
        }

        if (!found && !exactMatch) {
            for (Subtitle subtitle : listFoundSubtitles) {
                subtitle.setSubtitleMatchType(SubtitleMatchType.EVERYTHING);
                subtitle.setQuality(this.videoFileParser.getQualityKeyword(subtitle.getFilename()));
                Logger.instance.debug("getSubtitlesFiltered: found EVERYTHING match: " + subtitle.getFilename());
                listFilteredSubtitles.add(subtitle);
            }
        }
        return listFilteredSubtitles;
    }

    private boolean checkKeywordSubtitleMatch(Subtitle subtitle, String keywordsFile) {
    	String keywordsSub = videoFileParser.getQualityKeyword(subtitle.getFilename());
    	
    	boolean foundKeywordMatch = false;
    	if (keywordsFile.equalsIgnoreCase(keywordsSub)){
    		foundKeywordMatch = true;
    	}else{
    		foundKeywordMatch = keywordCheck(keywordsFile, keywordsSub);
    	}
    	return foundKeywordMatch;
	}

	private boolean keywordCheck(String videoFileName, String subFileName) {
    	Logger.instance.trace("SubtitleControl", "keywordCheck", "");
        boolean foundKeywordMatch = false;

        videoFileName = videoFileName.toLowerCase();
        subFileName = subFileName.toLowerCase();

        if (videoFileName.contains("dl") && subFileName.contains("dl")
        		&& videoFileName.contains("720p") && subFileName.contains("720p")
                && videoFileName.contains("web") && subFileName.contains("web")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("dl") && subFileName.contains("dl")
        		&& videoFileName.contains("1080p") && subFileName.contains("1080p")
                && videoFileName.contains("web") && subFileName.contains("web")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("hdtv") && subFileName.contains("hdtv")
                && videoFileName.contains("720p") && subFileName.contains("720p")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("1080p") && subFileName.contains("1080p")
                && videoFileName.contains("bluray") && subFileName.contains("bluray")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("720p") && subFileName.contains("720p")
                && videoFileName.contains("bluray") && subFileName.contains("bluray")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("xvid") && subFileName.contains("xvid")
                && videoFileName.contains("dvdrip") && subFileName.contains("dvdrip")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("xvid") && subFileName.contains("xvid")
                && videoFileName.contains("hdtv") && subFileName.contains("hdtv")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("720p") && subFileName.contains("720p")
                && videoFileName.contains("brrip") && subFileName.contains("brrip")
                && videoFileName.contains("xvid") && subFileName.contains("xvid")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("ts") && subFileName.contains("ts")
                && videoFileName.contains("xvid") && subFileName.contains("xvid")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("bdrip") && subFileName.contains("bdrip")
                && videoFileName.contains("xvid") && subFileName.contains("xvid")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("480p") && subFileName.contains("480p")
                && videoFileName.contains("brrip") && subFileName.contains("brrip")
                && videoFileName.contains("xvid") && subFileName.contains("xvid")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("720p") && subFileName.contains("720p")
                && videoFileName.contains("brrip") && subFileName.contains("brrip")
                && videoFileName.contains("x264") && subFileName.contains("x264")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("dvdscreener") && subFileName.contains("dvdscreener")
                && videoFileName.contains("xvid") && subFileName.contains("xvid")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("r5") && subFileName.contains("r5")
                && videoFileName.contains("xvid") && subFileName.contains("xvid")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("cam") && subFileName.contains("cam")
                && videoFileName.contains("xvid") && subFileName.contains("xvid")) {
            foundKeywordMatch = true;
        } else if (videoFileName.contains("hdtv") && subFileName.contains("hdtv")
                && videoFileName.contains("x264") && subFileName.contains("x264")) {
            foundKeywordMatch = true;
        }

        return foundKeywordMatch;
    }
}
